package com.party.pay.service.refund;

import cn.jpush.api.utils.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.party.common.utils.BigDecimalUtils;
import com.party.core.model.YesNoStatus;
import com.party.core.model.activity.ActStatus;
import com.party.core.model.activity.Activity;
import com.party.core.model.activity.ActivityType;
import com.party.core.model.counterfoil.Counterfoil;
import com.party.core.model.counterfoil.CounterfoilBusiness;
import com.party.core.model.counterfoil.CounterfoilType;
import com.party.core.model.goods.Goods;
import com.party.core.model.goods.GoodsCoupons;
import com.party.core.model.member.MemberAct;
import com.party.core.model.order.*;
import com.party.core.service.activity.IActivityService;
import com.party.core.service.counterfoil.ICounterfoilBusinessService;
import com.party.core.service.counterfoil.ICounterfoilService;
import com.party.core.service.goods.IGoodsCouponsService;
import com.party.core.service.goods.IGoodsService;
import com.party.core.service.member.IMemberActService;
import com.party.core.service.member.biz.MemberPersonalCountBizService;
import com.party.core.service.order.IOrderFormService;
import com.party.core.service.order.IOrderRefundTradeService;
import com.party.pay.model.query.TradeStatus;
import com.party.pay.model.refund.AliPayRefundResponse;
import com.party.pay.model.refund.WechatPayRefundResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.function.Function;

/**
 * 退款业务
 * 
 * @author yy-pc
 *
 */
@Service
public class RefundOrderBizService {

	@Autowired
	IOrderFormService orderFormService;

	@Autowired
	IMemberActService memberActService;

	@Autowired
	IActivityService activityService;

	@Autowired
	IGoodsService goodsService;

	@Autowired
	IGoodsCouponsService goodsCouponsService;

	@Autowired
	IOrderRefundTradeService orderRefundTradeService;
	@Autowired
	private ICounterfoilBusinessService counterfoilBusinessService;

	@Autowired
	private MemberPersonalCountBizService memberPersonalCountBizService;

	@Autowired
	private ICounterfoilService counterfoilService;

	Logger logger = LoggerFactory.getLogger(getClass());

	/**
	 * 退款更改状态
	 * 
	 * @param orderId
	 * @param paymentWay
	 */
	@Transactional(readOnly = false)
	public void refund(String orderId, Object object, Integer paymentWay) throws Exception {
		/************* 更改业务状态 *****************/
		OrderForm orderForm = orderFormService.get(orderId);
		orderForm.setIsPay(PaymentState.NO_PAY.getCode()); // 支付状态更改为未付款
		if (orderForm.getPayment() > Float.valueOf("0.0")) {
			orderForm.setStatus(OrderStatus.ORDER_STATUS_REFUND.getCode()); // 订单状态更改为已退款
		} else {
			orderForm.setStatus(OrderStatus.ORDER_STATUS_OTHER.getCode()); // 订单状态更改为其他
		}
		
		if (orderForm.getPaymentWay().equals(PaymentWay.WECHAT_PAY.getCode())) {
			orderForm.setTradeState(TradeStatus.WX_REFUND.getCode()); // 交易状态已退款
		} else if (orderForm.getPaymentWay().equals(PaymentWay.ALI_PAY.getCode())) {
			orderForm.setTradeState(TradeStatus.ALI_TRADE_CLOSED.getCode()); // 交易状态已关闭
		}
		orderForm.setUpdateDate(new Date());
		orderFormService.update(orderForm);

		if (OrderType.ORDER_ACTIVITY.getCode().equals(orderForm.getType())
				|| OrderType.ORDER_COURSE.getCode().equals(orderForm.getType())) {
			// 活动——更改活动报名状态
			MemberAct dbMemberAct = memberActService.findByOrderId(orderId);
			dbMemberAct.setCheckStatus(ActStatus.ACT_STATUS_AUDIT_REJECT.getCode()); // 审核拒绝
			dbMemberAct.setJoinin(YesNoStatus.NO.getCode()); // 取消
			memberActService.update(dbMemberAct);

			CounterfoilBusiness counterfoilBusiness = counterfoilBusinessService.findByBusinessId(dbMemberAct.getId());
			if (null != counterfoilBusiness) {
				String counterfoilId = counterfoilBusiness.getCounterfoilId();
				Counterfoil counterfoil = counterfoilService.get(counterfoilId);
				counterfoil.setJoinNum(counterfoil.getJoinNum() - 1);
				counterfoilService.update(counterfoil);
			}

			String actId = dbMemberAct.getActId();
			Activity act = activityService.get(actId);
			try {
				act.setOrderNum(act.getOrderNum() - 1);
				Double totalMoney = BigDecimalUtils.sub(act.getTotalMoney(), orderForm.getPayment());
				totalMoney = BigDecimalUtils.round(totalMoney, 2);
				act.setTotalMoney(totalMoney);
				act.setJoinNum(act.getJoinNum() - 1);
				activityService.update(act);
			} catch (Exception e) {
				logger.error("活动退款处理冗余数据异常", e);
			}

			if (OrderType.ORDER_ACTIVITY.getCode().equals(orderForm.getType())) {
				try {
					memberPersonalCountBizService.updateActivityNumMoney(act.getMember(), dbMemberAct.getMemberId(), orderForm.getPayment(), false);
				} catch (Exception e) {
					logger.error("实时更新活动报名金额/数量异常 ", e);
				}
			}
		}

		/************* 更改核销码状态为无效 *****************/
		GoodsCoupons goodsCoupon = new GoodsCoupons();
		goodsCoupon.setOrderId(orderId);
		List<GoodsCoupons> goodsCoupons = goodsCouponsService.list(goodsCoupon);
		for (GoodsCoupons coupons : goodsCoupons) {
			coupons.setStatus(0);
			goodsCouponsService.update(coupons);
		}

		if (orderForm.getPayment() > Float.valueOf("0.0")) {
			/************* 持久化退款交易信息 *****************/
			OrderRefundTrade orderTrade = new OrderRefundTrade();
			orderTrade.setOrderFormId(orderForm.getId());

			if (OrderType.ORDER_ACTIVITY.getCode().equals(orderForm.getType())) {
				orderTrade.setOrigin(1);// 来源于活动
			} else if (OrderType.ORDER_NOMAL.getCode().equals(orderForm.getType())
					|| OrderType.ORDER_CUSTOMIZED.getCode().equals(orderForm.getType())) {
				orderTrade.setOrigin(0);// 来源于商品
			}

			String transactionId = null;
			String responseData = null;

			OrderForm t = orderFormService.get(orderId);
			
			if (PaymentWay.WECHAT_PAY.getCode().equals(paymentWay)) {
				WechatPayRefundResponse response = (WechatPayRefundResponse) object;
				transactionId = response.getTransactionId();
				responseData = JSONObject.toJSONString(response);
				t.setTradeState(TradeStatus.WX_REFUND.getCode());
				orderFormService.update(t);
			} else if (PaymentWay.ALI_PAY.getCode().equals(paymentWay)) {
				AliPayRefundResponse response = (AliPayRefundResponse) object;
				transactionId = response.getTradeNo();
				responseData = JSONObject.toJSONString(response);
				t.setTradeState(TradeStatus.ALI_TRADE_CLOSED.getCode());
				orderFormService.update(t);
			}

			orderTrade.setTransactionId(transactionId);
			orderTrade.setType(orderForm.getPaymentWay());
			orderTrade.setData(responseData);
			orderRefundTradeService.insert(orderTrade);
		}
	}

	/**
	 * 更新预定成功人数
	 * 
	 * @param orderId
	 */
	@Transactional(readOnly = false)
	public void updateJoinNum(String orderId) {
		OrderForm orderForm = orderFormService.get(orderId);
		// 成功的订单
		List<OrderForm> orderForms = orderFormService.getOrder(orderForm.getGoodsId(), null, false);

		if (OrderType.ORDER_ACTIVITY.getCode().equals(orderForm.getType())) {
			// 更新活动报名成功人数
			Activity activity = activityService.get(orderForm.getGoodsId());
			activity.setJoinNum(orderForms.size());
			activityService.update(activity);
		} else if (OrderType.ORDER_NOMAL.getCode().equals(orderForm.getType()) || OrderType.ORDER_CUSTOMIZED.getCode().equals(orderForm.getType())) {
			// 更新商品预定成功人数
			Goods goods = goodsService.get(orderForm.getGoodsId());
			goods.setJoinNum(orderForms.size());
			goodsService.update(goods);
		}
	}

	/**
	 * 处理退款业务
	 * 
	 * @param orderId
	 * @param object
	 * @param paymentWay
	 * @throws Exception
	 */
	@Transactional(readOnly = false)
	public void updateRefundBusiness(String orderId, Object object, Integer paymentWay, Function function) throws Exception {
		refund(orderId, object, paymentWay);
		updateJoinNum(orderId);
		if (null != function) {
			function.apply(null);
		}
	}


	/**
	 * 免费活动拒绝业务处理
	 * @param orderId 订单id
	 * @param memberActId 活动报名id
	 */
	public void freeActivityReject(String orderId, String memberActId, Function function) {
		if (StringUtils.isNotEmpty(orderId)) {
			/************* 更改业务状态 *****************/
			OrderForm orderForm = orderFormService.get(orderId);
			orderForm.setIsPay(PaymentState.NO_PAY.getCode()); // 支付状态更改为未付款
			orderForm.setStatus(OrderStatus.ORDER_STATUS_OTHER.getCode()); // 订单状态更改为其他
			orderFormService.update(orderForm);
		}

		// 活动——更改活动报名状态
		MemberAct dbMemberAct = memberActService.get(memberActId);
		dbMemberAct.setCheckStatus(ActStatus.ACT_STATUS_AUDIT_REJECT.getCode()); // 审核拒绝
		dbMemberAct.setJoinin(YesNoStatus.NO.getCode()); // 取消
		memberActService.update(dbMemberAct);

		CounterfoilBusiness counterfoilBusiness = counterfoilBusinessService.findByBusinessId(memberActId);
		if (null != counterfoilBusiness) {
			String counterfoilId = counterfoilBusiness.getCounterfoilId();
			Counterfoil counterfoil = counterfoilService.get(counterfoilId);
			counterfoil.setJoinNum(counterfoil.getJoinNum() - 1);
			counterfoilService.update(counterfoil);
		}

		String actId = dbMemberAct.getActId();
		Activity act = activityService.get(actId);
		act.setJoinNum(act.getJoinNum() - 1);
		activityService.update(act);

		// 免费活动, 个人统计活动数量-1
		if (dbMemberAct.getCounterfoilType().equals(CounterfoilType.TYPE_FREE.getCode())) {
			try {
				memberPersonalCountBizService.updateActivityNum(act.getMember(), dbMemberAct.getMemberId(), false);
			} catch (Exception e) {
				logger.error("实时更新活动报名数量异常 ", e);
			}
		}

		/************* 更改核销码状态为无效 *****************/
		GoodsCoupons goodsCoupon = new GoodsCoupons();
		goodsCoupon.setGoodsId(dbMemberAct.getActId());
		goodsCoupon.setMemberId(dbMemberAct.getMemberId());
		List<GoodsCoupons> goodsCoupons = goodsCouponsService.list(goodsCoupon);
		for (GoodsCoupons coupons : goodsCoupons) {
			coupons.setStatus(0);
			goodsCouponsService.update(coupons);
		}

		if (null != function) {
			Integer activityType = activityService.getActivityType(act);
			if (null != activityType && ActivityType.COURSE.getCode().equals(activityType)) {
				function.apply(null);
			}
		}
	}
}
